/*
 * Amkai Enterprise Solution (AES.) 
 * Copyright 2004 by Amkai(TM), Inc.
 * www.amkai.com
 * 
 * Project: webservice
 * Package: com.amkai.aes.webservice.binary.objecthandler
 * File: DepartmentsListHandler.java
 * Created: Feb 21, 2006 10:12:39 AM
 * Author: johnny 
 * 
 */
package com.amkai.aes.webservice.binary.objecthandler;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.Hibernate;

import com.amkai.aes.aescommon.exceptions.AccessException;
import com.amkai.aes.aescommon.login.errorcodes.LoginErrorCodes;
import com.amkai.aes.aescommon.manager.DepartmentManager;
import com.amkai.aes.aescommon.service.binary.job.DepartmentsListJob;
import com.amkai.aes.aescommon.service.result.DepartmentsListResult;
import com.amkai.aes.generatedbeans.common.Location;
import com.amkai.aes.generatedbeans.common.Zip;
import com.amkai.aes.generatedbeans.common.ZipCode;
import com.amkai.aes.generatedbeans.organization.BusinessGroup;
import com.amkai.aes.generatedbeans.organization.Department;
import com.amkai.aes.generatedbeans.organization.Facility;
import com.amkai.aes.generatedbeans.passport.DepartmentSpecificRole;
import com.amkai.aes.generatedbeans.tree.Node;
import com.amkai.aes.generatedbeans.tree.NodeKind;
import com.amkai.aes.webservice.binary.JobObjectHandler;
import com.amkai.common.extensions.hibernate.config.SiteManager;
import com.amkai.common.extensions.hibernate.config.manager.SessionManager;
import com.amkai.extensions.server.version.VersionControl;
import com.sun.corba.se.pept.encoding.InputObject;

/**
 * DepartmentsListHandler
 * 
 * @author johnny Description:
 * 
 */
public class DepartmentsListHandler implements JobObjectHandler<DepartmentsListJob, Serializable, DepartmentsListResult> {

	private static final Log log = LogFactory.getLog(DepartmentsListHandler.class);

	/**
	 * Overriden method
	 * 
	 * @param job
	 * @param object
	 * @return
	 * @throws Exception
	 * @see com.amkai.aes.webservice.binary.JobObjectHandler#createNewObject(E,
	 *      InputObject)
	 * 
	 */
	@SuppressWarnings("unchecked")
	public DepartmentsListResult process(DepartmentsListJob job, Serializable object) throws Exception {
		LoginErrorCodes code = LoginErrorCodes.FAILED;
		DepartmentsListResult result = new DepartmentsListResult();

		List<Department> list = null;
		SessionManager sm = SiteManager.Start();
		try {
			VersionControl wc = new VersionControl();
			wc.versionControll(job.getClientCodeVersion(),job.getClientDBVersion(), null);

			sm.openSession();
			//GYAND AES-18520
			if(job.isDownload()) {
				Department d = sm.get(Department.class, job.getDepartment().getId());
				Department dd = (Department) sm.execute(
						"select d FROM Department d " + "left join fetch d.location " + "left join fetch d.departmentType "
								+ "left join fetch d.departmentType.kindWrapper left join fetch d.parent where d.id = "+d.getId()).uniqueResult();
				loadDepartment(dd, sm);
				result.setDepartment(dd);
			} else if(job.isLiteVersion()) {
				list = new ArrayList<Department>();
				List<Long>dids = null;
				if(job.getDepartment() != null) {
					Department d = sm.get(Department.class, job.getDepartment().getId());
					dids = sm.execute("select d.id FROM Department d where d.parent.id = "+d.getParent().getId()).list();
					
				} else {
					dids = sm.execute("select d.id FROM Department d ").list();
				}
				for(Long did : dids) {
					Department d = sm.get(Department.class, did);
					d.getName();
					d.getShortName();
					d.getTimeZone();
					list.add(d);
				}
			} else {
				//GYAND AES-18520
				if(job.getDepartment() != null) {
					Department d = sm.get(Department.class, job.getDepartment().getId());
					list = sm.execute(
							"select d FROM Department d " + "left join fetch d.location " + "left join fetch d.departmentType "
									+ "left join fetch d.departmentType.kindWrapper left join fetch d.parent where d.parent.id = "+d.getParent().getId()).list();
					
				} else {
					list = sm.execute(
							"select d FROM Department d " + "left join fetch d.location " + "left join fetch d.departmentType "
									+ "left join fetch d.departmentType.kindWrapper left join fetch d.parent").list();
				}
				for (Department dep : list) {
					loadDepartment(dep,sm);
				}
			}
			code = LoginErrorCodes.SUCCESS;
		} catch (Exception ex) {
			if (ex instanceof AccessException) {
				code = ((AccessException) ex).getCode();
				result.setObjects(((AccessException) ex).getObjects());
			} else {
				log.error("", ex);
				
				throw ex;
			}
		} finally {
			sm.closeSession();
		}
		result.setErrorCode(code);
		
		// AES-18528
		if (list != null) {
			for(Department d : list) {
				d.setDepartmentSpecificRoles(new HashSet<DepartmentSpecificRole>());
			}
		}
		if (result.getDepartment() != null) {
			result.getDepartment().setDepartmentSpecificRoles(new HashSet<DepartmentSpecificRole>());
		}
		
		result.setDepartments(list);
		return result;
	}

	//GYAND AES-18520
	private void loadDepartment(Department dep, SessionManager sm) throws Exception {
		Hibernate.initialize(dep);
		Location loc = dep.getLocation();
		if (loc != null) {
			loc.getLine1();
			loc.getLine2();
			ZipCode zCode = loc.getZipCode();
			if (zCode != null) {
				if (zCode.getCity() != null) {
					zCode.getCity().getName();
				}
				Zip z = zCode.getZip();
				if (z != null) {
					z.getName();
					if (z.getState() != null) {
						z.getState().getName();
					}
					if (z.getCountry() != null) {
						z.getCountry().getName();
					}
					if (z.getCounty() != null) {
						z.getCounty().getName();
					}
				}
			}
			if (loc.getPhone() != null) {
				loc.getPhone().getNumber();
			}
		}

		
		if(dep.getMainOffice() != null){
			dep.getMainOffice().getId();
			dep.getMainOffice().getName();
		}
		
		Set<Node> facilities = dep.getChildren();
		if (facilities != null) {
			for (Node o_fac : facilities) {
				if (o_fac instanceof Facility) {
					Facility facility = (Facility) o_fac;
					facility.getKind();
					facility.getName();
				}
			}
		}
		//#12512
		if (dep.getParent() != null) {
			if (dep.getParent().getKind() == NodeKind.BUSINESS_GROUP) {
				BusinessGroup bg = sm.get(BusinessGroup.class, dep.getParent().getId());
				dep.setParent(bg);
				bg.getName();
				bg.getId();
				bg.getKind();
				bg.getLevel();
			}
		}
		// KKORNEL: AES-16950
		if (!DepartmentManager.isDepartmentValid(dep)) {
			dep.putTranzientProperty(DepartmentManager.BE_UNDER_CREATE, Boolean.TRUE);
		}
	}
	//GYAND AES-18520

}
